package com.example.weight.m3u8;

import android.util.Log;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class M3U8Util {
    private static Pattern M3U8_EXTINF_PAT;
    private static Pattern M3U8_EXT_X_KEY_PAT;
    private static Pattern M3U8_STREAM_PAT;
    private static Pattern URL_PAT;

    static {
        M3U8_STREAM_PAT = Pattern.compile("#EXT-X-STREAM-INF:PROGRAM-ID=(\\d+),BANDWIDTH=(\\d+)", Pattern.DOTALL);
        M3U8_EXTINF_PAT = Pattern.compile("#EXTINF:([\\d\\.]+),", Pattern.DOTALL);
        M3U8_EXT_X_KEY_PAT = Pattern.compile("#EXT-X-KEY:METHOD=AES-128,URI=\"([^,\"]+)\",IV=(\\w+)", Pattern.DOTALL);
        URL_PAT = Pattern.compile("(#EXT-X-KEY:[^\n]+)?((http|https)://[^\"\n]+)", Pattern.DOTALL);
    }
    
    //调用需要异步处理
    public static M3U8File getM3U8FileFromUrl(String url) {
        M3U8File m3U8File2;
        int n = M3U8File.STREAM_LIST;
        M3U8File m3u8ListFile = null;
        while (true) {
            m3U8File2 = m3u8ListFile;
            if (n != M3U8File.STREAM_LIST) {
                break;
            }
            if (m3u8ListFile != null) {
                ArrayList<M3U8ListItem> m3u8List = m3u8ListFile.m3u8List;
                int n2;
                if (m3u8List.size() > 2) {
                    n2 = 1;
                } else {
                    n2 = 0;
                }
                url = m3u8List.get(n2).url;
            }
            Log.e("m3u8", "start parse m3u8 file " + m3u8ListFile);
            InputStream streamFromNet = null;
            try {
                streamFromNet = new URL(url).openConnection().getInputStream();
            } catch (Exception e) {
                e.printStackTrace();
                break;
            }
            if (streamFromNet == null) {
                m3U8File2 = null;
                break;
            }
            Map<String, Integer> map = new HashMap<>();
            map.put(url, 13069);
            m3u8ListFile = parseM3u8ListFile(new BufferedReader(new InputStreamReader(streamFromNet)), map);
            n = m3u8ListFile.type;
        }
        return m3U8File2;
    }

    private static M3U8File parseM3u8ListFile(BufferedReader paramBufferedReader, Map<String, Integer> paramMap) {
        M3U8File localM3U8File = new M3U8File();
        StringBuilder localStringBuilder = new StringBuilder();
        int n = -1;
        Object urlObj = null;
        while (true) {
            Object lineObj;
            try {
                lineObj = paramBufferedReader.readLine();
                Matcher matcher;
                if (lineObj != null) {
                    Log.e("path", (String) lineObj);
                    localStringBuilder.append((String) lineObj).append("\n");
                    switch (n) {
                        case 0: {
                            localM3U8File.m3u8List.get(localM3U8File.m3u8List.size() - 1).url = (String) lineObj;
                            n = -1;
                            continue;
                        }
                        case 2: {
                            localM3U8File.urlList.add((String) lineObj);
                            n = -1;
                            continue;
                        }
                    }
                    matcher = M3U8_STREAM_PAT.matcher((CharSequence) lineObj);
                    if (matcher.find()) {
                        if (localM3U8File.m3u8List == null) {
                            localM3U8File.type = M3U8File.STREAM_LIST;
                            localM3U8File.m3u8List = new ArrayList<>();
                        }
                        lineObj = new M3U8ListItem();
                        ((M3U8ListItem) lineObj).bandwidth = Integer.parseInt(matcher.group(2));
                        ((M3U8ListItem) lineObj).programId = Integer.parseInt(matcher.group(1));
                        localM3U8File.m3u8List.add((M3U8ListItem) lineObj);
                        n = 0;
                        continue;
                    }
                    matcher = M3U8_EXT_X_KEY_PAT.matcher((CharSequence) lineObj);
                    if (matcher.find()) {
                        localM3U8File.type = M3U8File.PLAY_LIST;
                        String group = matcher.group(1);
                        if (paramMap != null) {
                            if (paramMap.containsKey(md5(group)))
                                continue;
                        } else {
                            localM3U8File.urlList.add((String) lineObj);
                            continue;
                        }
                        localM3U8File.keyList.add(group);
                        continue;
                    }
                    if (M3U8_EXTINF_PAT.matcher((CharSequence) lineObj).find()) {
                        localM3U8File.type = M3U8File.PLAY_LIST;
                        n = 2;
                    }
                } else {
                    try {
                        paramBufferedReader.close();
                        localM3U8File.content = localStringBuilder.toString();
                        Log.d("M3U8Util", "end parse m3u8 file " + localM3U8File.content);
                        return localM3U8File;
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    paramBufferedReader.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
    }

    private final static char[] DIGITS_LOWER = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    protected static char[] encodeHex(final byte[] array) {
        final int length = array.length;
        final char[] array2 = new char[length << 1];
        int i = 0;
        int n = 0;
        while (i < length) {
            final int n2 = n + 1;
            array2[n] = DIGITS_LOWER[(array[i] & 0xF0) >>> 4];
            n = n2 + 1;
            array2[n2] = DIGITS_LOWER[array[i] & 0xF];
            ++i;
        }
        return array2;
    }

    public static String md5(String s) {
        if (s == null) {
            return null;
        }
        try {
            final MessageDigest instance = MessageDigest.getInstance("MD5");
            instance.update(s.getBytes());
            s = new String(encodeHex(instance.digest()));
            return s;
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

}
